﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using NHibernate.Cfg;
using NHibernate;
using NHibernate.Linq;
using MySql.Data;
using ASPPanificadora.classes;

namespace ASPPanificadora.fabrica
{
    public class Fabrica
    {
        ISession session = null;
        ITransaction transaction = null;
                
        private static ISessionFactory _sessionFactory;

        private static ISessionFactory SessionFactory
        {
            get
            {
                if (_sessionFactory == null)
                {
                    var config = new Configuration();
                    config.Configure();

                    config.AddAssembly("ASPPanificadora");

                    _sessionFactory = config.BuildSessionFactory();
                }
                return _sessionFactory;
            }
        }

        public static ISession OpenSession()
        {
            return SessionFactory.OpenSession();
        }

        public ISession sessao()
        {
            if (session == null || !(session.IsConnected || session.IsOpen))
            {
                session = OpenSession();
                transaction = session.BeginTransaction();
            }
            return session;
        }

        public void fechaSessao()
        {
            session.Close();
        }

        public string Salva(object objeto)
        {
            try
            {
                using (var sessaoPadrao = sessao())
                {
                    sessaoPadrao.SaveOrUpdate(objeto);
                    transaction.Commit();
                }
                return "Salvo com sucesso";
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                return ex.Message.ToString();
            }
        }
        
        public string SalvaPedido(Pedido pedido, IList<ItemPedido> itens)
        {
            try
            {
                using (var sessaoPedido = sessao())
                {
                    if (pedido.Id == 0)
                    {
                        sessaoPedido.Save(pedido);
                        transaction.Commit();
                    }
                    else
                        sessaoPedido.Update(pedido);

                }
                using (var sessaoPedido = sessao())
                {
                    var itensSalvos = sessaoPedido.Query<ItemPedido>().Where(a => a.IdPedido == pedido.Id).ToList();

                    foreach (var item in itensSalvos)
                    {
                        ItemPedido itemSalvo = itens.Where(a => a.Id == item.Id).FirstOrDefault();
                        if (itemSalvo != null)
                        {
                            if (itemSalvo != item)
                                sessaoPedido.Update(item);

                            itens.Remove(itens.Where(a => a.Id == item.Id).FirstOrDefault());
                        }
                        else
                        {
                            sessaoPedido.Delete(item);
                        }
                    }

                    foreach (var item in itens)
                    {
                        item.IdPedido = pedido.Id;
                        sessaoPedido.Save(item);
                    }
                    transaction.Commit();
                    return "Salvo com sucesso";
                }
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                return ex.Message.ToString();
            }
        }

        public string SalvaTipoUsuario(TipoUsuario tipoUsuario, IList<TelaSistema> listaTelasSistema)
        {
            try
            {
                using (var sessaoTipoUsuario = sessao())
                {
                    if (tipoUsuario.Id == 0)
                    {
                        sessaoTipoUsuario.Save(tipoUsuario);
                    }
                    else
                    {
                        sessaoTipoUsuario.Update(tipoUsuario);
                    }
                    transaction.Commit();
                }
                using (var sessaoTipoUsuario = sessao())
                {
                    var itensSalvos = sessaoTipoUsuario.Query<LigTipoUsuarioTelaSistema>().Where(a => a.IdTipoUsuario == tipoUsuario.Id)
                        .Fetch(a => a.TelaSistema)
                        .ToList();

                    foreach (var item in itensSalvos)
                    {
                        TelaSistema itemSalvo = listaTelasSistema.Where(a => a.Id == item.IdTelaSistema).FirstOrDefault();

                        if (itemSalvo != null)
                        {
                            listaTelasSistema.Remove(itemSalvo);
                        }
                        else
                        {
                            sessaoTipoUsuario.Delete(item);
                        }
                    }

                    foreach (var item in listaTelasSistema)
                    {
                        sessaoTipoUsuario.Save(new LigTipoUsuarioTelaSistema() { IdTelaSistema = item.Id, IdTipoUsuario = tipoUsuario.Id });
                    }
                    transaction.Commit();
                    return "Salvo com sucesso";
                }
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                return ex.Message.ToString();
            }
        }

        public string SalvaUsuario(Usuario usuario)
        {
            try
            {
                if (usuario.Id == 0)
                {
                    using (var sessaoUsuario = sessao())
                    {
                        usuario.Senha = CriptografiaMD5.CriptografarSenhaMD5("123456");
                        sessaoUsuario.Save(usuario);
                        transaction.Commit();
                    }
                }
                else
                {
                    Usuario usuarioSalvo;
                    using (var sessaoUsuario = sessao())
                    {
                        usuarioSalvo = sessaoUsuario.Query<Usuario>().Where(a => a.Id == usuario.Id).FirstOrDefault();
                    }
                    using (var sessaoUsuario = sessao())
                    {
                        if (usuario.Senha == null || usuario.Senha.Equals("") || usuario.Senha.Length == 0) 
                            usuario.Senha = usuarioSalvo.Senha;
                        sessaoUsuario.Update(usuario);
                        transaction.Commit();
                    }
                }
                return "Salvo com sucesso";
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                return ex.Message.ToString();
            }
        }

        public string SalvaCompra(Compra compra, IList<ItemPedido> listaItemPedido)
        {
            try
            {
                IList<ItemCompra> itens = compra.ItemCompra;
                compra.ItemCompra = null;
                using (var sessaoCompra = sessao())
                {
                    if (compra.Id == 0)
                    {
                        sessaoCompra.Save(compra);
                        transaction.Commit();
                    }
                    else
                        sessaoCompra.Update(compra);

                }
                using (var sessaoCompra = sessao())
                {
                    var itensSalvos = sessaoCompra.Query<ItemCompra>().Where(a => a.IdCompra == compra.Id).ToList();
                    

                    foreach (var item in itensSalvos)
                    {
                        ItemCompra itemSalvo = itens.Where(a => a.Id == item.Id).FirstOrDefault();
                        if (itemSalvo != null)
                        {
                            if (itemSalvo != item)
                                sessaoCompra.Update(item);

                            itens.Remove(itens.Where(a => a.Id == item.Id).FirstOrDefault());
                        }
                        else
                        {
                            sessaoCompra.Delete(item);
                        }
                    }

                    foreach (var item in itens)
                    {
                        item.IdCompra = compra.Id;
                        sessaoCompra.Save(item);
                    }

                    foreach (var item in listaItemPedido)
                    {
                        sessaoCompra.Update(item);
                    }
                    transaction.Commit();
                    return "Salvo com sucesso";
                }
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                return ex.Message.ToString();
            }
        }

        public string SalvaVenda(Venda venda, IList<ItemVenda> listaItemVenda)
        {
            try
            {
                IList<ItemVenda> itens = venda.ItemVenda;
                venda.ItemVenda = null;
                using (var sessaoVenda = sessao())
                {
                    if (venda.Id == 0)
                    {
                        sessaoVenda.Save(venda);
                        transaction.Commit();
                    }
                    else
                        sessaoVenda.Update(venda);

                }
                using (var sessaoVenda = sessao())
                {
                    var itensSalvos = sessaoVenda.Query<ItemVenda>().Where(a => a.IdVenda == venda.Id).ToList();

                    foreach (var item in itensSalvos)
                    {
                        ItemVenda itemSalvo = listaItemVenda.Where(a => a.Id == item.Id).FirstOrDefault();
                        if (itemSalvo != null)
                        {
                            if (itemSalvo != item)
                                sessaoVenda.Update(item);

                            listaItemVenda.Remove(listaItemVenda.Where(a => a.Id == item.Id).FirstOrDefault());
                        }
                        else
                        {
                            sessaoVenda.Delete(item);
                        }
                    }

                    foreach (var item in listaItemVenda)
                    {
                        item.IdVenda = venda.Id;
                        sessaoVenda.Save(item);
                    }

                    transaction.Commit();
                    return "Salvo com sucesso";
                }
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                return ex.Message.ToString();
            }
            return string.Empty;
        }

        public string ExcluiVenda(int idVenda)
        {
            if (idVenda != 0)
            {
                try
                {
                    using (var sessaoVenda = sessao())
                    {
                        var itensSalvos = sessaoVenda.Query<ItemVenda>().Where(a => a.IdVenda == idVenda).ToList();
                        if (itensSalvos != null)
                        {
                            foreach (ItemVenda item in itensSalvos)
                            {
                                sessaoVenda.Delete(item);
                            }
                            transaction.Commit();
                        }
                        
                    }

                    using (var sessaoVenda = sessao())
                    {
                        Venda venda = sessaoVenda.Query<Venda>().Where(a => a.Id == idVenda).FirstOrDefault();
                        sessaoVenda.Delete(venda);
                        transaction.Commit();
                    }
                    return "Excluído com sucesso";
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    return ex.Message.ToString();
                }
            }
            else
            {
                return "Código inválido";
            }
        }
        
        public string FechaComprasVendas()
        {
            try
            {
                using (var sessaoFechamento = sessao())
                {
                    var listaCompras = sessaoFechamento.Query<Compra>().Where(a => a.FechamentoCompra == false).ToList();
                    foreach (var item in listaCompras)
                    {
                        item.FechamentoCompra = true;
                    }
                    var listaVendas = sessaoFechamento.Query<Venda>().Where(a => a.FechamentoVenda == false).ToList();
                    foreach (var item in listaVendas)
                    {
                        item.FechamentoVenda = true;
                    }
                    transaction.Commit();
                }
                return "Salvo com sucesso";
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                return ex.Message.ToString();
            }
        }

        public string SalvaProducao(Producao producao)
        {
            try
            {
                IList<ItemProducao> listaItemProducao = producao.ListaItemProducao;
                producao.ListaItemProducao = null;
                using (var sessaoProducao = sessao())
                {
                    if (producao.Id == 0)
                    {
                        sessaoProducao.Save(producao);
                        transaction.Commit();
                    }
                    else
                        sessaoProducao.Update(producao);

                }
                using (var sessaoProducao = sessao())
                {
                    var itensSalvos = sessaoProducao.Query<ItemProducao>().Where(a => a.IdProducao == producao.Id).ToList();

                    foreach (var item in itensSalvos)
                    {
                        ItemProducao itemSalvo = listaItemProducao.Where(a => a.Id == item.Id).FirstOrDefault();
                        if (itemSalvo != null)
                        {
                            if (itemSalvo != item)
                                sessaoProducao.Update(item);

                            listaItemProducao.Remove(listaItemProducao.Where(a => a.Id == item.Id).FirstOrDefault());
                        }
                        else
                        {
                            sessaoProducao.Delete(item);
                        }
                    }

                    foreach (var item in listaItemProducao)
                    {
                        item.IdProducao = producao.Id;
                        sessaoProducao.Save(item);
                    }

                    transaction.Commit();
                    return "Salvo com sucesso";
                }
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                return ex.Message.ToString();
            }
            return string.Empty;
        }
    }
}
